
#include "MainFrame.h"
#include "MainApplication.h"
#include "Layout.h"
#include "StringUtil.h"
#include "FontsetNotebook.h"
#include "ConfigDialog.h"
#include "AboutBox.h"

#include <wx/stdpaths.h>
#include <wx/filename.h>

IMPLEMENT_DYNAMIC_CLASS( MainFrame, wxDocParentFrame )

//--- Event table
BEGIN_EVENT_TABLE( MainFrame, wxDocParentFrame )

EVT_MENU( wxID_EXIT, MainFrame::OnExit )

END_EVENT_TABLE()
//--- Event table

MainFrame::MainFrame(void)
{
    // Load the settings.  If they are not valid (ie. first time the application
    // is run), prompt the user to enter the settings.
    ConfigSettings* settings = ConfigSettings::GetInstancePtr();
    if ( !settings->IsValid() )
    {
        ConfigDialog dlg( this );
        if ( dlg.ShowModal() == wxID_OK )
        {
        }
    }

    // Initialize the PNG image handler:
    wxImage::AddHandler( new wxPNGHandler() );
    wxImage::AddHandler( new wxGIFHandler() );
}

MainFrame::MainFrame( wxDocManager* docManager, wxFrame* parent, wxWindowID id, const wxString& title )
{
    // Load the settings.  If they are not valid (ie. first time the application
    // is run), prompt the user to enter the settings.
    ConfigSettings* settings = ConfigSettings::GetInstancePtr();
    if ( !settings->IsValid() )
    {
        ConfigDialog dlg( this );
        if ( dlg.ShowModal() == wxID_OK )
        {
            settings->ReadSettings();
        }
    }

    // Initialize the PNG image handler:
    wxImage::AddHandler( new wxPNGHandler() );

    Create( docManager, parent, id, title );
}

MainFrame::~MainFrame(void)
{
    mAuiManager.UnInit();
}

bool MainFrame::Create( wxDocManager* docManager, wxFrame* parent, wxWindowID id, const wxString& title )
{
    //bool success = wxDocParentFrame::Create( docManager, parent, id, title, wxDefaultPosition, wxDefaultSize );
    bool success = wxDocParentFrame::Create( docManager, parent, id, title, wxDefaultPosition, wxSize( 700, 460 ) );
    if ( success )
    {
        CreateControls();
    }

    return success;
}

void MainFrame::CreateControls()
{
    SetMenuBar( CreateMenuBar() );
    CreateToolbar();
    this->CreateStatusBar( 1, wxST_SIZEGRIP, ID_STATUS_BAR );
    mAuiManager.SetManagedWindow( this );

	mTabbedProjectContainer = new FontsetNotebook( this, ID_TABBED_PROJECT_CONTAINER, wxDefaultPosition, wxDefaultSize, wxAUI_NB_CLOSE_ON_ACTIVE_TAB|wxAUI_NB_DEFAULT_STYLE|wxAUI_NB_SCROLL_BUTTONS|wxAUI_NB_WINDOWLIST_BUTTON );
/*
    StringUtil::String name = "Fontset";
    if ( mTabbedProjectContainer->GetPageCount() )
    {
        std::stringstream stream;
        stream << mTabbedProjectContainer->GetPageCount();
        name += stream.str();
    }
    FontsetPanelExt* page = new FontsetPanelExt( name, mTabbedProjectContainer, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL );
    mTabbedProjectContainer->AddPage( page, name, true );
*/
    //AddFontset();

    mAuiManager.AddPane( mTabbedProjectContainer, wxAuiPaneInfo().CenterPane().Name( _( "Project" ) ) );
    mTabbedProjectContainer->Modify( false );

    //mAuiManager.AddPane( new wxPanel( this, wxID_ANY ), wxAuiPaneInfo().CenterPane().Name( _( "Fontset" ) ) );

    mAuiManager.Update();
}

wxMenuBar* MainFrame::CreateMenuBar()
{
    wxMenuBar* mainMenu = new wxMenuBar();

    wxMenu* fileMenu = new wxMenu();
    fileMenu->Append( wxID_NEW, _( "New Project\tCtrl+N" ) );

    wxMenuItem* newFontset = new wxMenuItem( fileMenu, wxID_ANY, _( "New Fontset\tShift+Ctrl+N" ), wxT("Add a new fontset to the project") );
    fileMenu->Append( newFontset );
    this->Connect( newFontset->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrame::OnNewFontset ) );

    fileMenu->AppendSeparator();
    fileMenu->Append( wxID_OPEN, _( "Open\tCtrl+O" ) );
    fileMenu->Append( wxID_SAVE, _( "Save\tCtrl+S" ) );
    fileMenu->Append( wxID_SAVEAS, _( "Save as...\tShift+Ctrl+S" ) );
    fileMenu->AppendSeparator();
    
    wxMenuItem* projectInfo = new wxMenuItem( fileMenu, wxID_ANY, _( "Project information..." ), _T( "Edit the project information" ) );
    fileMenu->Append( projectInfo );
    this->Connect( projectInfo->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrame::OnProjectInformation ) );

    fileMenu->AppendSeparator();

    MainApplication* mainApp = wxDynamicCast( wxTheApp, MainApplication );
    if ( mainApp )
    {
        wxMenu* mruMenu = new wxMenu();
        mainApp->GetDocManager()->FileHistoryUseMenu( mruMenu );
        //fileMenu->Append( mruMenu );

        fileMenu->AppendSeparator();
    }

    fileMenu->Append( wxID_EXIT, _( "Exit\tAlt+F4" ) );

    //mainApp->GetDocManager()->FileHistoryUseMenu( fileMenu );

    wxMenu* viewMenu = new wxMenu();

    wxMenuItem* viewGrid = new wxMenuItem( viewMenu, wxID_ANY, wxT( "Gridlines" ), wxT( "View cell grid lines" ), wxITEM_CHECK );
    viewMenu->Append( viewGrid );
    this->Connect( viewGrid->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrame::OnViewGridlines ) );
	this->Connect( viewGrid->GetId(), wxEVT_UPDATE_UI, wxUpdateUIEventHandler( MainFrame::OnUpdateViewGridlines ) );

    wxMenuItem* viewWidths = new wxMenuItem( viewMenu, wxID_ANY, wxT( "Widths" ), wxT( "View font widths" ), wxITEM_CHECK );
    viewMenu->Append( viewWidths );
    this->Connect( viewWidths->GetId(), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrame::OnViewWidths ) );
	this->Connect( viewWidths->GetId(), wxEVT_UPDATE_UI, wxUpdateUIEventHandler( MainFrame::OnUpdateViewWidths ) );


    wxMenu* helpMenu = new wxMenu();
    helpMenu->Append( wxID_ABOUT, _T( "About..." ) );
    this->Connect( wxID_ABOUT, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler( MainFrame::OnAboutBox ) );

    mainMenu->Append( fileMenu, _( "File" ) );
    mainMenu->Append( viewMenu, _( "View" ) );
    mainMenu->Append( helpMenu, _( "Help" ) );

    return mainMenu;
}

wxToolBar* MainFrame::CreateToolbar()
{
    wxString appDir = wxStandardPaths::Get().GetExecutablePath();
    wxFileName appPath( appDir );
    appDir = appPath.GetPath() + wxFileName::GetPathSeparator();

    //wxToolBar* toolBar = new wxToolBar( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTB_FLAT );
    wxToolBar* toolBar = this->CreateToolBar( wxTB_FLAT | wxTB_HORIZONTAL );
	toolBar->SetToolBitmapSize( wxSize( 20,20 ) );
	wxToolBarToolBase* newProj = toolBar->AddTool( wxID_NEW, wxT("New project"), wxBitmap( appDir + wxT("images/icon_new_project.png"), wxBITMAP_TYPE_ANY ), wxNullBitmap, wxITEM_NORMAL, wxT("Create a new project"), wxT("Create a new project") );
	wxToolBarToolBase* newFontset = toolBar->AddTool( ID_NEW_FONTSET, wxT("New fontset"), wxBitmap( appDir + wxT("images/icon_new_fontset.png"), wxBITMAP_TYPE_ANY ), wxNullBitmap, wxITEM_NORMAL, wxT("Add a new fontset to the project"), wxT("Add a new fontset to the project") );
    this->Connect( newFontset->GetId(), wxEVT_COMMAND_TOOL_CLICKED, wxCommandEventHandler( MainFrame::OnNewFontset ) );
	toolBar->AddTool( wxID_OPEN, wxT("Open file"), wxBitmap( appDir + wxT("images/icon_open_file.png"), wxBITMAP_TYPE_ANY ), wxNullBitmap, wxITEM_NORMAL, wxT("Load a project file"), wxT("Load a project file") );
	toolBar->AddTool( wxID_SAVE, wxT("Save file"), wxBitmap( appDir + wxT("images/icon_save_project.png"), wxBITMAP_TYPE_ANY ), wxNullBitmap, wxITEM_NORMAL, wxT("Save the current project"), wxT("Save the current project") );
	toolBar->AddSeparator();
	wxToolBarToolBase* viewGridlines = toolBar->AddTool( wxID_ANY, wxT("View gridlines"), wxBitmap( appDir + wxT("images/icon_view_gridlines.png"), wxBITMAP_TYPE_ANY ), wxNullBitmap, wxITEM_CHECK, wxT("Toggle gridline display"), wxT("Toggle gridline display") );
    this->Connect( viewGridlines->GetId(), wxEVT_COMMAND_TOOL_CLICKED, wxCommandEventHandler( MainFrame::OnViewGridlines ) );
	this->Connect( viewGridlines->GetId(), wxEVT_UPDATE_UI, wxUpdateUIEventHandler( MainFrame::OnUpdateViewGridlines ) );
	wxToolBarToolBase* viewWidths = toolBar->AddTool( wxID_ANY, wxT("View widths"), wxBitmap( appDir + wxT("images/icon_view_widths.png"), wxBITMAP_TYPE_ANY ), wxNullBitmap, wxITEM_CHECK, wxT("Toggle character width display"), wxT("Toggle character width display") );
    this->Connect( viewWidths->GetId(), wxEVT_COMMAND_TOOL_CLICKED, wxCommandEventHandler( MainFrame::OnViewWidths ) );
	this->Connect( viewWidths->GetId(), wxEVT_UPDATE_UI, wxUpdateUIEventHandler( MainFrame::OnUpdateViewWidths ) );
	toolBar->Realize();

    return toolBar;
}

void MainFrame::OnExit( wxCommandEvent& event )
{
    Close();
}

void MainFrame::OnNewFontset( wxCommandEvent& event )
{
    mTabbedProjectContainer->AddFontset();
}

void MainFrame::OnProjectInformation( wxCommandEvent& event )
{
    mTabbedProjectContainer->EditProjectInformation();
}

void MainFrame::OnViewGridlines( wxCommandEvent& event )
{
    mTabbedProjectContainer->SetViewGridlines( !mTabbedProjectContainer->GetViewGridlines() );
}

void MainFrame::OnUpdateViewGridlines( wxUpdateUIEvent& event )
{
    event.Check( mTabbedProjectContainer->GetViewGridlines() );
}

void MainFrame::OnViewWidths( wxCommandEvent& event )
{
    mTabbedProjectContainer->SetViewWidths( !mTabbedProjectContainer->GetViewWidths() );
}

void MainFrame::OnUpdateViewWidths( wxUpdateUIEvent& event )
{
    event.Check( mTabbedProjectContainer->GetViewWidths() );
}

void MainFrame::OnAboutBox( wxCommandEvent& event )
{
    AboutBox* aboutDlg = new AboutBox( this );

    // Set the application name
    aboutDlg->SetAppName( wxTheApp->GetAppName() );

    // Set the application version
    aboutDlg->SetVersion( "1.0.0" );

    // Set copyright message
    aboutDlg->SetCopyright( wxString::Format( wxT( "Copyright %c %i %s" ), (wxChar)0x00A9, wxDateTime::Now().GetYear(), _( "Dratek Software" ) ) );

    // Set build info (if not set, a default message will be used.)
    aboutDlg->SetCustomBuildInfo( wxString::Format( wxT( "%s %s" ), AboutBox::GetBuildInfo( AboutBox::wxBUILDINFO_LONG ).GetData(), _T( "\nProgrammed by Chad M. Draper" ) ) );

    // Set header bitmap
    wxString appDir = wxStandardPaths::Get().GetExecutablePath();
    wxFileName appPath( appDir );
    appDir = appPath.GetPath() + wxFileName::GetPathSeparator();
    aboutDlg->SetHeaderBitmap( appDir + wxT( "images/splash_image.png" ) );

    // Apply changes
    aboutDlg->ApplyInfo();

    // Show the dialog
    aboutDlg->ShowModal();

    // Destroy the dialog
    aboutDlg->Destroy();
}
